from django.views import View
from django.shortcuts import render
from django.shortcuts import HttpResponse
from django.shortcuts import redirect
from django.urls import reverse
from django.http.response import JsonResponse
from django.utils.decorators import method_decorator
from django.views.decorators.csrf import csrf_exempt
from django.utils.safestring import mark_safe
from django.core.paginator import Paginator #用来实现分页
from django.core.paginator import EmptyPage #判断页面是否存在
from django.core.paginator import PageNotAnInteger #判断输入的页面是否时整数
from web.utils.encrypt import uid
from web.forms.issue import IssueForm
from web.forms.issue import IssueReplyForm
from web.forms.invite import InviteForm
from web import models
import json

class CheckFilter(object):
    def __init__(self,name,datalist,request):
        self.request = request
        self.datalist = datalist
        self.name=name

    def __iter__(self):
        for item in self.datalist:
            value_list=self.request.GET.getlist(self.name)
            if str(item[0]) in value_list:
                value_list.remove(str(item[0]))
                query_dict=self.request.GET.copy()
                query_dict._mutable=True
                query_dict.setlist(self.name,value_list)
                if 'page' in query_dict:
                    query_dict.pop('page')
                yield {
                    'key':item[0],
                    'value':item[1],
                    'checked': True,
                    'url':f'{self.request.path}?{query_dict.urlencode()}'
                }
            else:
                value_list.append(item[0])
                query_dict = self.request.GET.copy()
                query_dict._mutable = True
                query_dict.setlist(self.name, value_list)
                if 'page' in query_dict:
                    query_dict.pop('page')
                yield {
                    'key': item[0],
                    'value': item[1],
                    'url': f'{self.request.path}?{query_dict.urlencode()}'
                }




@method_decorator(csrf_exempt,name='dispatch')
class IssueView(View):
    '''
    问题展示视图
    '''
    def get(self, request, *args, **kwargs):
        #筛选条件
        allow_filter_name=['issue_type','status','priority','assign']
        #晒选条件
        condition={}
        for item in allow_filter_name:
            value_list=request.GET.getlist(item)
            if not value_list:
                continue
            else:
                condition[f'{item}__in']=value_list
        form=IssueForm(request=request)
        issuesset=models.Issues.objects.filter(project=request.tracer.project).filter(**condition).order_by('id')
        lists=Paginator(issuesset,5)  #对数据库获取的数据进行 每页为5 的分页
        page=request.GET.get('page')  #获取  页码信息
        try:
            cons=lists.page(page)  #返回前端传递过来的页码数据
        except EmptyPage:
            cons=lists.page(lists.num_pages)  #页面存在报错  返回最后一页
        except PageNotAnInteger:
            cons=lists.page(1)     #页面不是整数的报错 返回第一页
        #项目问题类型列表
        issue_type=models.IssuesType.objects.filter(project=request.tracer.project).values_list('id','title')
        #项目相关用户列表
        project_user_list=[(request.tracer.project.creator_id,request.tracer.project.creator.username),]
        project_join_list=models.ProjectUser.objects.filter(
            project=request.tracer.project).values_list('user_id', 'user__username')
        project_user_list.extend(project_join_list)

        return render(request, 'manage/issue.html',
                      {'form':form,'issuelist':cons,
                       'status_filter':CheckFilter('status',models.Issues.status_choices,request),
                       'priority_filter': CheckFilter('priority',models.Issues.mode_choices, request),
                       'issues_type_filter':CheckFilter('issues_type',issue_type,request),
                       'assign_filter': CheckFilter('assign', project_user_list, request),
                       'invite_form':InviteForm,
                                                    })

    def post(self,request,*args,**kwargs):
        '''
        创建项目
        :param request:
        :param args:
        :param kwargs:
        :return:
        '''
        form=IssueForm(request=request,data=request.POST)
        if form.is_valid():

            form.instance.project=request.tracer.project
            form.instance.creator=request.tracer.user
            form.save()

            return JsonResponse({'code': 200, 'data': '创建成功', 'error': ''})
        else:
            print(form.errors)
            return JsonResponse({'code':400,'data':'','error':form.errors})


class IssueDetailView(View):
    '''
    问题详细页编辑
    '''
    def get(self,request,project_id,issue_id,*args,**kwargs):
        obj=models.Issues.objects.filter(id=issue_id,project_id=project_id).first()
        form=IssueForm(request=request,instance=obj)
        return render(request,'manage/issue_detail.html',{'form':form,'id':issue_id})

@method_decorator(csrf_exempt,name='dispatch')
class IssueRecordView(View):
    '''
    问题记录
    '''
    def get(self,request,project_id,issue_id,*args,**kwargs):
        #获取问题的操作记录

        issue_reply_set=models.IssuesReply.objects.filter(issues_id=issue_id, issues__project_id=project_id).order_by('-id')
        data_list=[]
        for item in issue_reply_set:

            data={
                'id':item.id,
                'parent_id':item.reply.id if item.reply else '',
                'content':item.content,
                'datetime':item.create_datetime.strftime('%Y-%m-%d %H:%M'),
                'reply_type':item.get_reply_type_display(),
                'creator':item.creator.username
            }

            # print(getattr(item,'id'))
            data_list.append(data)

        return JsonResponse({'code': 200, 'data': data_list, 'error': ''})

    def post(self,request,project_id,issue_id,*args,**kwargs):
        form=IssueReplyForm(data=json.loads(request.body.decode()))
        if form.is_valid():
            form.instance.reply_type=2
            form.instance.issues_id=issue_id
            form.instance.creator=request.tracer.user
            form.save()
            return JsonResponse({'code': 200, 'data': '', 'error': ''})
        else:
            print(form.errors)
            return JsonResponse({'code': 400, 'data': '', 'error': form.errors})

@method_decorator(csrf_exempt,name='dispatch')
class IssueChangeView(View):
    '''

    '''
    def post(self, request,project_id,issue_id,*args,**kwargs):
        #获取更新的问题对象
        issue_object=models.Issues.objects.filter(id=issue_id,project_id=project_id).first()
        data_dict=json.loads(request.body.decode())
        name=data_dict.get('name')
        value=data_dict.get('value')
        field_object = models.Issues._meta.get_field(name)
        #文本类型
        if name in ['subject','desc','start_date','end_date',]:
            if not value:
                if  not field_object.null:
                    return JsonResponse({'code': 400, 'data': '', 'error': '不允许为空'})
                else:
                    setattr(issue_object,name,None)
            else:
                setattr(issue_object,name,value)
            issue_object.save()
            #生成操作记录
            change_record=f'{field_object.verbose_name}更新为:{value}'
            models.IssuesReply.objects.create(reply_type=1,
                                              issues=issue_object,
                                              creator=request.tracer.user,
                                              content=change_record
                                              )
            return JsonResponse({'code': 200, 'data': '更新成功', 'error': ''})
        #FK类型  指派的话 要判断是否是参与者或者是创建者
        elif name in ['issues_type','module','parent','assign']:
            if name == 'assign':
                #是否项目的创建者
                #是否时项目的参与者
                if value is None:
                    instance = None
                elif value == str(request.tracer.project.creator.id):
                    instance=request.tracer.project.creator
                elif models.ProjectUser.objects.filter(project_id=project_id,user_id=value).first():
                    instance=models.ProjectUser.objects.filter(project_id=project_id,user_id=value).first().user
                else:
                    instance=None
                setattr(issue_object, name, instance)
                issue_object.save()
                change_record = f'{field_object.verbose_name}更新为:{str(instance)}'
                models.IssuesReply.objects.create(reply_type=1,
                                                  issues=issue_object,
                                                  creator=request.tracer.user,
                                                  content=change_record
                                                  )
            else:
                #用户选择为空
                if not value:
                    if not field_object.null:
                        return JsonResponse({'code': 400, 'data': '', 'error': '不允许为空'})
                    else:
                        setattr(issue_object, name,None)
                        change_record = f'{field_object.verbose_name}更新为:{value}'
                #用户选择不为空
                else:
                    #用户提交的字段是否
                    instance=field_object.remote_field.model.objects.filter(id=value,project_id=project_id).first()
                    if not instance:
                        return JsonResponse({'code':400,'data':'','error':'您选择的值不存在'})

                    setattr(issue_object,name,instance)
                issue_object.save()
                # 生成操作记录
                change_record = f'{field_object.verbose_name}更新为:{str(instance)}'
                models.IssuesReply.objects.create(reply_type=1,
                                                  issues=issue_object,
                                                  creator=request.tracer.user,
                                                  content=change_record
                                                  )
        #choices 字段
        if name in ['priority','status','mode']:
            selected_text=None
            for key,text in field_object.choices:
                if str(key)==value:
                    selected_text=text
            if not selected_text:
                return JsonResponse({'code': 400, 'data': '', 'error': '您选择的值不存在'})
            setattr(issue_object,name,value)
            issue_object.save()
            change_record = f'{field_object.verbose_name}更新为:{selected_text}'
            models.IssuesReply.objects.create(reply_type=1,
                                              issues=issue_object,
                                              creator=request.tracer.user,
                                              content=change_record
                                              )

        #M2M 类型
        if name =='attention':
            if not isinstance(value,list):
                return JsonResponse({'code': 400, 'data': '', 'error': '数据格式错误'})
            if not value:
                issue_object.attention.set([])

                change_record = f'{field_object.verbose_name}更新为:空'
                models.IssuesReply.objects.create(reply_type=1,
                                                  issues=issue_object,
                                                  creator=request.tracer.user,
                                                  content=change_record
                                                  )
                issue_object.save()
            else:
                user_dict={str(request.project.creator.id):request.project.creator.username}
                project_user_list=models.ProjectUser.objects.filter(project_id=project_id)
                for item in project_user_list:
                    user_dict[str(item.user.id)]=item.user.username
                username_list=[]
                for user_id in value:
                    username=user_dict[user_id]
                    if not username:
                        return JsonResponse({'code': 400, 'data': '', 'error': '数据格式错误'})
                    else:
                        username_list.append(username)
                issue_object.attention.set(value)
                issue_object.save()
                change_record = f'{field_object.verbose_name}更新为:{"".join(username_list)}'
        #数据库更新 & 生成操作记录
        return JsonResponse({'code':200,'data':'','error':''})


class InviteView(View):
    def post(self,request,*args,**kwargs):

        form=InviteForm(data=request.POST)
        if form.is_valid():
            if request.tracer.project.creator!=request.tracer.user:
                form.add_error('period', '无权创建邀请码')
                return JsonResponse({'code': 400, 'data': '', 'error': form.errors})

            else:
                form.instance.project=request.tracer.project
                form.instance.code =uid(request.tracer.user.mobile_phone)
                form.instance.creator=request.tracer.user
                instance=form.save()
                url_path=reverse('web:invite_join',kwargs={'code':instance.code})
                url = f'{request.scheme}://{request.get_host()}{url_path}'
                return JsonResponse({'code': 200, 'data': url, 'error': ''})
        else:
            return JsonResponse({'code': 400, 'data': '', 'error': form.errors})

class InviteJoinView(View):
    def get(self,request,code,*args,**kwargs):
        invite_obj=models.ProjectInvite.objects.filter(code=code).first()
        if not invite_obj:
            return HttpResponse('邀请码不存在')
        if  invite_obj.project.creator==request.tracer.user:
            return HttpResponse('您已经在项目中')
        exists=models.ProjectUser.objects.filter(project=invite_obj.project,user=request.tracer.user).exists()
        if exists:
            return HttpResponse('您已经在项目中')
        #判断项目的人数限制
        max_cout=request.tracer.price_policy.project_member
        #现有成员
        count=models.ProjectUser.objects.filter(project=invite_obj.project).count()
        if count>=max_cout:
            return HttpResponse('项目人员已满')
        #邀请码是否过期
        import datetime
        current_datetime=datetime.datetime.now()
        deadline=invite_obj.create_datetime+datetime.timedelta(minutes=invite_obj.period)
        if current_datetime>deadline:
            return HttpResponse('邀请码已经过期')
        #邀请码的数量限制
        if  not invite_obj.count:
            models.ProjectUser.objects.create(project=invite_obj.project,user=request.tracer.user)
            return HttpResponse('创建成功！')
        else:
            if invite_obj.use_count>=invite_obj.count:
                return HttpResponse('邀请码已用完')
            else:
                models.ProjectUser.objects.create(project=invite_obj.project, user=request.tracer.user)
                return HttpResponse('创建成功！')

        return render(request,'manage/project_join.html')